package com.llg.util.formula;

import javassist.*;
import org.apache.commons.lang3.RandomUtils;

import java.util.concurrent.atomic.AtomicInteger;

public abstract class Formula {
    private static final AtomicInteger index = new AtomicInteger();

    @SuppressWarnings(value = "all")
    public static <T> T create(Class<?> father, String methodStr, String formula) throws CannotCompileException, InstantiationException, NotFoundException, IllegalAccessException {
        try {
            ClassPool classPool = ClassPool.getDefault();
            CtClass ctClass = classPool.makeClass(father.getName() + "impl" + index.getAndIncrement());
            ctClass.setSuperclass(classPool.get(father.getName()));
            CtMethod ctMethod = CtNewMethod.make(
                    methodStr + "{" +
                            "return (int)(" + formula + ");" +
                            "}", ctClass);
            ctClass.addMethod(ctMethod);
            return (T) ctClass.toClass().newInstance();
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * a,b中小的那个
     *
     * @param a
     * @param b
     * @return
     */
    protected double min(double a, double b) {
        return Math.min(a, b);
    }

    protected double min(int a, int b) {
        return min((double) a, (double) b);
    }

    /**
     * a,b中大的那个
     *
     * @param a
     * @param b
     * @return
     */
    protected double max(double a, double b) {
        return Math.max(a, b);
    }

    protected double max(int a, int b) {
        return max((double) a, (double) b);
    }

    /**
     * [a,b)随机
     *
     * @param a
     * @param b
     * @return
     */
    protected int random(int a, int b) {
        return RandomUtils.nextInt(a, b);
    }

    /**
     * a的b次幂
     *
     * @param a
     * @param b
     * @return
     */
    protected double pow(double a, double b) {
        return Math.pow(a, b);
    }

    protected double pow(int a, int b) {
        return pow((double) a, (double) b);
    }

    protected double pow(double a, int b) {
        return pow(a, (double) b);
    }

    protected double pow(int a, double b) {
        return pow((double) a, b);
    }

    /**
     * 自然对数的ln的反函数
     *
     * @param a
     * @return
     */
    protected double exp(double a) {
        return Math.exp(a);
    }

    protected double exp(int a) {
        return exp((double) a);
    }

    /**
     * 向下取整
     *
     * @param a
     * @return
     */
    protected double floor(double a) {
        return Math.floor(a);
    }

    /**
     * 向上取整
     *
     * @param a
     * @return
     */
    protected double ceil(double a) {
        return Math.ceil(a);
    }

    /**
     * 四舍五入
     *
     * @param a
     * @return
     */
    protected double round(double a) {
        return Math.round(a);
    }

}
